/**
 * Created by Eric.Dou on 4/14/14.
 */
define(function (require, exports) {
    var $ = require('lib/jquery');
    require('lib/plugins/jquery.element.js')($);
    function hasProperty(obj, proName) {
        if (typeof(obj) == 'undefined')
            return false;
        if (obj == null)
            return false;
        if (obj[proName] == undefined) {
            console.log('should include [' + proName + '] property.');
            console.log(obj);
            return false;
        }
        return true;
    }

    exports.hasPro = hasProperty;

    exports.hash = function (str) {
        var hash = 0;
        for (i = 0; i < str.length; i++) {
            char = str.charCodeAt(i);
            hash = ((hash << 5) - hash) + char;
            /* hash * 31 + c */
        }
        return hash;
    };

    exports.getFuncName = function (callback) {
        var _text = callback.toString();
        var _scriptArr = document.scripts;
        for (var i = 0; i < _scriptArr.length; i++) {
            var _start = _scriptArr[ i].text.indexOf(_text);
            if (_start != -1) {
                if (/^function\s*\(.*\).*\r\n/.test(_text)) {
                    var _tempArr = _scriptArr[ i].text.substr(0, _start).split('\r\n');
                    return _tempArr[_tempArr.length - 1].replace(/(var)(\s*)/g, '').replace(/=/g, '');
                } else {
                    return _text.match(/^function\s*([^\(]+).*\r\n/)[1];
                }
            }
        }
    };
    function appHtmlToComp(target, theHtmlContent) {
        //if is error process,then print a empty html element.
        var toInnerHtml = '<p></p>';
        if (hasProperty(theHtmlContent, 'content')) {
            toInnerHtml = theHtmlContent['content'];
        }
        else if (hasProperty(theHtmlContent, 'sub')) {
            toInnerHtml = madeInnerHtml(theHtmlContent['sub']);
        }
        if ($.isArray(toInnerHtml)) {
            $.each(toInnerHtml, function (i, data) {
                $(data).appendTo(target);
            });
        } else {
            $(toInnerHtml).appendTo(target);
        }
    }

    exports.appendHtmlToComponent = appHtmlToComp;

    function madeInnerHtml(elements) {
        if ($.isArray(elements)) {
            var elementHtmlArray = [];
            $.each(elements, function (i, element) {
                var toInnerHtml = "";
                if ($.isArray(element)) {
                    toInnerHtml = madeInnerHtml(element);
                }
                else {
                    toInnerHtml = madeTag(element);
                }
                elementHtmlArray[i] = toInnerHtml;
            });
            return elementHtmlArray;
        }
        return madeTag(elements);
    };

    function madeTag(element) {
        var hasTag = true;
        var tag = "";
        if (!hasProperty(element, 'tag')) {
            hasTag = false;
        }
        else {
            tag = element['tag'];
        }
        var attr = {};
        if (hasProperty(element, 'attr')) {
            attr = element['attr'];
        }
        var toInnerHtml = '';
        if (hasProperty(element, 'content')) {
            toInnerHtml = element['content'];
        }
        else if (hasProperty(element, 'sub')) {
            toInnerHtml = madeInnerHtml(element['sub']);
        }
        if (hasTag) {
            if ($.type(toInnerHtml) == 'string') {
                if (toInnerHtml.indexOf('<') >= 0) {
                    var element = $.element[tag]();
                    element.attr(attr).append(toInnerHtml);
                    toInnerHtml = element;
                } else {
                    toInnerHtml = $.element[tag](toInnerHtml).attr(attr);
                }

            } else if ($.isArray(toInnerHtml)) {
                var parent = $.element[tag]().attr(attr);
                $.each(toInnerHtml, function (i, data) {
                    $(data).appendTo(parent);
                });
                toInnerHtml = parent;
            }
            else if ($.type(toInnerHtml) == 'object') {
                toInnerHtml = $.element[tag](toInnerHtml).attr(attr);
            }
        }
        return toInnerHtml;
    }

    exports.lazyLoadCompont = function (lazyConfigs, callBack) {
        if (lazyConfigs == undefined || null == lazyConfigs) {
            return false;
        }
        //should be have target property.
        if (!hasProperty(lazyConfigs, 'target')) {
            return false;
        }
        //should be have target property.
        if (lazyConfigs['target'] != null && lazyConfigs['target'].length <= 0) {
            return false;
        }
        var lazyLoadSub = {
            lazyLoadContent: "<p>loading...</p>",
            url: "",
            lazyMethod: "getJSON",
            data: null,
            callBackOptions: {}
        };
        $.extend(lazyLoadSub, lazyConfigs);
        //add the the lazy loading content into the component inner.
        $(lazyLoadSub.target).html(lazyLoadSub.lazyLoadContent);
        //loading the content from server.
        //the method possible options: "getJson","get","load","post"
        var lazyMethod = lazyLoadSub['lazyMethod'];
        var target = lazyLoadSub ['target'];
        handleFn = function (data, status) {
            //load content finished,then put the lazyLoad flag to false.
            //options['lazyLoad'] = false;
            //if there are a handle process then to handle it by itself
            if (hasProperty(lazyLoadSub, 'handle') && $.isFunction(lazyLoadSub['handle'])) {
                var innerHtml = lazyLoadSub['handle']($, data, status);
                if ('success' == status) {
                    if (hasProperty(lazyLoadSub, 'afterSuccess') && $.isFunction(lazyLoadSub['afterSuccess'])) {
                        lazyLoadSub['afterSuccess']($, data, status);
                    } else {
                        $(target).html('');
                    }
                    appHtmlToComp(target, {content: innerHtml});
                }
            } else {
                //if status code 200, using the default handing method.
                if ('success' == status) {
                    appHtmlToComp(target, data);
                }
            }
            callBack(lazyLoadSub.callBackOptions);
        };

        if (typeof(lazyLoadSub.data) == 'undefined'&&null!=lazyLoadSub.data) {
            $[lazyMethod](lazyLoadSub.url, handleFn)
        } else {
            $[lazyMethod](lazyLoadSub.url, lazyLoadSub.data, handleFn)
        }
    };

});
